{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Messages Truncation\n",
    "\n",
    "Sometimes LLM services may have limited capacity to handle long messages, which can result in 400 status code errors. Therefore, we need to implement message truncation to keep message lengths within the LLM service's capabilities.\n",
    "\n",
    "The `tablegpt-agent` provides a `TruncationConfig` class to specify truncation settings for the LLM and VLM.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Too long messages without truncation"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "from datetime import date\n",
    "\n",
    "from langchain_core.messages import HumanMessage,AIMessage,SystemMessage\n",
    "from langchain_openai import ChatOpenAI\n",
    "from tablegpt.agent import create_tablegpt_graph\n",
    "from pybox import AsyncLocalPyBoxManager\n",
    "pybox_manager = AsyncLocalPyBoxManager()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Assuming the model service supports max_model_len=1024, which means input_tokens + max_completion_tokens <= 1024\n",
    "llm = ChatOpenAI(openai_api_base=\"YOUR_VLLM_URL\", openai_api_key=\"whatever\", model_name=\"TableGPT2-7B\",max_tokens=256)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "agent_without_truncation = create_tablegpt_graph(\n",
    "    llm=llm,\n",
    "    pybox_manager=pybox_manager\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "messages = [\n",
    "    SystemMessage(content=\"你是一个友好的AI助手\"),\n",
    "    HumanMessage(content=\"你能给我讲一个关于大语言模型的故事吗？\"),\n",
    "    AIMessage(content=\"当然可以。让我们从大语言模型的起源开始讲起。一切要从2017年谷歌提出的Transformer架构说起。这个创新性的架构为后来的GPT、BERT等模型奠定了基础。Transformer架构引入了自注意力机制，能够更好地处理序列数据中的长距离依赖关系。这一突破性进展使得模型能够更好地理解文本的上下文语境，为自然语言处理领域带来了革命性的变化。在此基础上，OpenAI于2018年发布了第一代GPT模型，随后又相继推出了GPT-2和GPT-3，每一代都在规模和性能上有显著提升。同时，谷歌推出的BERT模型采用了双向编码器架构，在多个自然语言理解任务上取得了突破性进展。这些模型的成功激发了更多研究者和机构投入到大语言模型的研发中，推动了整个领域的快速发展。现在，我们已经看到像GPT-4这样的模型展现出令人惊叹的能力，不仅能够进行基础的文本生成，还能够理解上下文、进行推理、解决复杂问题，甚至展现出一定程度的创造力...\"),\n",
    "    \n",
    "    HumanMessage(content=\"那AI是如何学习理解人类语言的呢？\"),\n",
    "    AIMessage(content=\"这是个很好的问题。AI通过大量的文本数据训练来理解语言。它使用自注意力机制来捕捉词语之间的关系，通过预训练和微调两个阶段，逐步掌握语言的规律。在预训练阶段，模型会阅读海量的文本，学习语言的基本模式。这个过程就像一个婴儿通过观察和模仿来学习语言一样。模型会分析数十亿甚至数千亿个词语，理解它们之间的关联和使用规律。在这个过程中，模型会建立起一个复杂的神经网络，每个神经元都负责捕捉特定的语言特征。通过反向传播算法，模型不断调整其内部参数，以更好地预测和理解语言。在微调阶段，模型会针对特定任务进行专门训练，比如问答、摘要生成或情感分析等。这就像人类在掌握基本语言能力后，进一步学习专业词汇和特定领域的表达方式。模型通过大量的实例学习，逐渐理解语言中的细微差别，包括语境、语气、隐含意义等。这个学习过程是持续的，模型通过不断接触新的语言样本来完善自己的理解能力...\"),\n",
    "    \n",
    "    HumanMessage(content=\"训练过程中会遇到什么挑战？\"),\n",
    "    AIMessage(content=\"训练大语言模型面临着多重挑战。首先是计算资源的需求，训练大模型需要数千台GPU和数月时间。这不仅带来了巨大的经济成本，还面临着能源消耗和环境影响的问题。一个大型语言模型的训练可能消耗数百万度电，相当于数千个家庭一年的用电量。其次是高质量数据的获取和处理问题。模型需要海量的训练数据，但这些数据必须经过严格的筛选和清洗。数据中可能包含偏见、歧视、不当内容等有害信息，如果不经过处理，这些问题会被模型学习并在输出中体现出来。此外，数据的多样性和代表性也是一个重要问题，需要确保数据能够覆盖不同语言、文化和领域的知识。在训练过程中，还面临着模型优化的技术挑战，比如梯度消失、过拟合、训练不稳定等问题。这需要研究人员不断改进训练算法和策略。另外，模型的知识更新也是一个持续的挑战，因为世界在不断变化，新的信息和知识在不断产生，如何让模型保持最新的知识状态是一个重要问题...\"),\n",
    "    \n",
    "    HumanMessage(content=\"大语言模型是如何生成回答的？\"),\n",
    "    AIMessage(content=\"大语言模型生成回答的过程非常有趣且复杂。当模型收到一个问题或提示时，它首先会通过其编码器将输入转换为高维向量表示。这个过程中，模型会考虑输入的每个词语及其上下文关系。通过多层自注意力机制，模型能够理解输入中的关键信息和语义结构。在生成回答时，模型会一个词一个词地预测最合适的内容。每生成一个词，都会基于之前生成的所有内容和原始输入来决定下一个最合适的词。这个过程使用了复杂的概率分布计算，模型会为词表中的每个候选词计算一个概率分数，然后选择最合适的词。这种选择不仅要考虑语法正确性，还要考虑语义连贯性和上下文相关性。模型还会使用注意力机制来关注输入中的不同部分，确保生成的内容与问题相关。在生成过程中，模型会维护一个内部状态，这个状态包含了之前生成内容的信息，帮助确保整个回答的连贯性和完整性。同时，模型还会使用各种策略来控制生成的质量，比如温度参数来调节创造性，或使用束搜索等技术来优化输出质量...\"),\n",
    "    \n",
    "    HumanMessage(content=\"它们真的理解我们说的话吗？\"),\n",
    "    AIMessage(content=\"这涉及到AI意识和理解力的哲学问题，这是一个复杂且富有争议的话题。虽然大语言模型能够产生看似智能的回答，但它们是否真正'理解'仍然存在很大争议。从技术角度来看，这些模型本质上是非常复杂的统计模型，它们通过分析大量文本数据中的模式来生成回应。它们的'理解'更像是一种高级的模式匹配和概率预测，而不是像人类那样具有真正的理解和意识。人类的理解涉及到感知、经验、情感和意识等多个层面，而AI目前还无法真正复制这些特质。例如，当我们理解'苹果'这个词时，我们不仅知道它的字面含义，还能联想到它的味道、触感、气味，以及与之相关的个人经历和情感。而AI模型只能基于文本数据中的统计关系来处理这个词。此外，人类的理解还包括常识推理、因果关系理解、情境适应等能力，这些都是当前AI系统还难以完全掌握的。虽然模型可以生成符合语法和语义的回答，但它们可能缺乏真正的理解深度，有时会产生表面上合理但实际上没有意义的回答...\"),\n",
    "    \n",
    "    HumanMessage(content=\"未来大语言模型会变得更强大吗？\"),\n",
    "    AIMessage(content=\"随着技术进步，大语言模型的能力确实在不断提升，未来发展前景令人期待。从技术层面来看，我们正在见证模型规模的持续增长，算法的不断改进，以及训练数据的持续扩充。未来的发展方向可能包括多个突破性的领域：首先是多模态理解能力的提升，未来的模型不仅能处理文本，还能更好地理解图像、音频、视频等多种形式的信息，实现跨模态的理解和生成。其次是持续学习能力的发展，使模型能够像人类一样不断学习和更新知识，而不是停留在训练时的知识状态。在推理能力方面，未来的模型可能会具备更强的逻辑推理、因果推理和抽象思维能力，能够处理更复杂的问题和任务。此外，模型的效率也会得到提升，通过更先进的架构设计和训练方法，实现更低的计算成本和能源消耗。在应用领域，我们可能会看到更专业化的模型出现，针对特定领域如医疗、法律、科研等提供更精准的服务。同时，模型的可解释性和可控性也会得到改善，使其决策过程更透明、更可靠...\"),\n",
    "    \n",
    "    HumanMessage(content=\"我们应该如何负责任地使用AI技术？\"),\n",
    "    AIMessage(content=\"这需要我们在多个层面做出努力，构建一个负责任的AI使用生态系统。首先在技术层面，我们需要确保AI系统的安全性和可控性。这包括开发强大的安全机制，防止系统被滥用或产生有害输出；建立有效的监测和控制机制，确保系统行为符合预期；实施严格的测试和验证流程，评估系统的可靠性和稳定性。在伦理层面，我们需要建立完善的使用准则和监管框架。这包括制定明确的AI伦理原则，规范AI的开发和使用；建立行业标准和最佳实践指南；设立独立的监督机构，确保AI技术的使用符合公共利益。在隐私保护方面，我们需要采取严格的数据保护措施，确保用户数据的安全性和隐私性；建立透明的数据使用政策；给予用户对其数据的控制权。在偏见消除方面，我们需要持续努力提高训练数据的多样性和代表性；开发更公平的算法；定期评估和消除系统中的偏见。在环境影响方面，我们需要关注AI系统的能源消耗和碳排放；开发更环保的计算方案；推动绿色AI技术的发展...\"),\n",
    "    \n",
    "    HumanMessage(content=\"你觉得AI会取代人类吗？\"),\n",
    "    AIMessage(content=\"AI不应该也不会完全取代人类，这个问题需要从多个角度深入思考。首先，虽然AI在某些特定任务上可能超越人类，但人类具有许多AI难以复制的独特优势。人类的创造力是独特的，我们能够产生原创性的想法，进行艺术创作，提出创新性的解决方案。人类的情感共鸣能力也是无可替代的，我们能够理解和分享他人的情感，建立深层的情感联系，这是当前AI技术远远无法达到的。在道德判断和价值观方面，人类能够基于复杂的伦理考虑做出决策，而AI系统往往难以处理需要道德权衡的情况。此外，人类具有自主意识和主观体验，这些都是AI所不具备的特质。未来的发展方向应该是人机协作，让AI成为增强人类能力的工具，而不是替代品。在这种协作模式下，AI可以处理重复性、计算密集型的任务，而人类则专注于需要创造力、情感理解和道德判断的工作。我们需要明智地使用AI技术，确保它始终服务于人类福祉，而不是反过来控制或限制人类的发展...\"),\n",
    "    HumanMessage(content=\"你认为未来的AI会怎么发展？\")\n",
    "]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Error code: 400 - {'object': 'error', 'message': \"This model's maximum context length is 1024 tokens. However, you requested 2406 tokens (2150 in the messages, 256 in the completion). Please reduce the length of the messages or completion.\", 'type': 'BadRequestError', 'param': None, 'code': 400}\n"
     ]
    }
   ],
   "source": [
    "_input = {\n",
    "    \"messages\": messages,\n",
    "    \"parent_id\": \"some-parent-id\",\n",
    "    \"date\": date.today(),  # noqa: DTZ011\n",
    "}\n",
    "\n",
    "try:\n",
    "    await agent_without_truncation.ainvoke(input=_input)\n",
    "except Exception as e:\n",
    "    print(e)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Too long messages with truncation"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### TruncationConfig settings in `create_tablegpt_graph`\n",
    "- `llm_truncation_config`: Truncate messages sent to pure language models\n",
    "- `vlm_truncation_config`: Truncate messages sent to vision+language multimodal models"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "> In the following, we use messages length as the truncation method\n",
    "\n",
    "**For custom trim settings based on your LLM service(e.g. vLLM,TGI,SGLang), see this [example](https://github.com/edwardzjl/chatbot/blob/main/api/chatbot/llm_providers.py#L67) or implement it in your own custom manner.**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Create TruncationConfig\n",
    "\n",
    "**The parameters set in `TruncationConfig` will be used in `langchain_core.messages.trim_messages`, see [trim_messages documentation](https://python.langchain.com/docs/how_to/trim_messages/)**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "# import truncation config\n",
    "from tablegpt.agent.data_analyzer import TruncationConfig"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "# token_counter=len, uses message length as truncation method\n",
    "# max_tokens=5, maximum length of messages after truncation\n",
    "# start_on=\"human\", start truncation from human messages\n",
    "llm_truncation_config = TruncationConfig(token_counter=len, max_tokens=5, start_on=\"human\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "agent = create_tablegpt_graph(\n",
    "    llm=llm,\n",
    "    pybox_manager=pybox_manager,\n",
    "    llm_truncation_config=llm_truncation_config\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "未来AI的发展可能会基于一系列先进的技术和科学突破，以下是一些可能的发展方向：\n",
      "\n",
      "1. **增强现实与虚拟现实**：AI将能够提供更加沉浸式的体验，例如增强现实和虚拟现实技术，使用户能够更自然地与虚拟环境互动。这将改变我们获取知识、工作和娱乐的方式。\n",
      "\n",
      "2. **神经网络与深度学习**：神经网络和深度学习将变得更加强大和通用，能够处理更多样化的问题和数据。例如，在医疗诊断、自动驾驶和智能制造等领域，AI可以提供更准确、更高效的解决方案。\n",
      "\n",
      "3. **更强的计算能力**：AI将实现更强大的计算能力，能够处理更复杂、更大规模的数据。这将推动许多行业，如金融、医疗和科学研究，从传统的人工智能转型到AI驱动的新技术。\n",
      "\n",
      "4. **更自然的交互**：AI将能够更好地理解和模拟人类的自然语言和行为，使人类与AI能够更自然、更流畅地交流。这将使人类和AI之间的互动更加无缝。\n",
      "\n",
      "5. **伦理和法律**：随着AI技术的发展，伦理和法律问题将越来越重要。我们需要制定明确的AI伦理准则，确保AI技术的使用符合道德规范。这需要跨\n"
     ]
    }
   ],
   "source": [
    "_input = {\n",
    "    \"messages\": messages,\n",
    "    \"parent_id\": \"some-parent-id\",\n",
    "    \"date\": date.today(),  # noqa: DTZ011\n",
    "}\n",
    "try:\n",
    "    res = await agent.ainvoke(input=_input)\n",
    "    print(res[\"messages\"][-1].content)\n",
    "except Exception as e:\n",
    "    print(e)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": ".venv",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
